package zserio.extension.java;

import zserio.ast.PackageName;
import zserio.extension.common.ExpressionFormatter;
import zserio.extension.common.PackedTypesCollector;

/**
 * FreeMarker template data context for all emitters.
 *
 * Holds all parameters used by FreeMarker template data.
 */
final class TemplateDataContext
{
    public TemplateDataContext(JavaExtensionParameters javaParameters, PackageName rootPackageName,
            PackedTypesCollector packedTypesCollector)
    {
        this.packedTypesCollector = packedTypesCollector;

        javaNativeMapper = new JavaNativeMapper(javaParameters.getWithWriterCode(), packedTypesCollector);
        javaRootPackageName = JavaFullNameFormatter.getFullName(rootPackageName);

        final JavaExpressionFormattingPolicy policy = new JavaExpressionFormattingPolicy(javaNativeMapper);
        javaExpressionFormatter = new ExpressionFormatter(policy);

        final JavaCaseExpressionFormattingPolicy casePolicy =
                new JavaCaseExpressionFormattingPolicy(javaNativeMapper);
        javaCaseExpressionFormatter = new ExpressionFormatter(casePolicy);

        final JavaSqlExpressionFormattingPolicy sqlPolicy =
                new JavaSqlExpressionFormattingPolicy(javaNativeMapper);
        javaSqlExpressionFormatter = new ExpressionFormatter(sqlPolicy);

        final JavaSqlLambdaExpressionFormattingPolicy sqlLambdaPolicy =
                new JavaSqlLambdaExpressionFormattingPolicy(javaNativeMapper);
        javaSqlLambdaExpressionFormatter = new ExpressionFormatter(sqlLambdaPolicy);

        final JavaLambdaExpressionFormattingPolicy lambdaPolicy =
                new JavaLambdaExpressionFormattingPolicy(javaNativeMapper);
        javaLambdaExpressionFormatter = new ExpressionFormatter(lambdaPolicy);

        withWriterCode = javaParameters.getWithWriterCode();
        withValidationCode = javaParameters.getWithValidationCode();
        withRangeCheckCode = javaParameters.getWithRangeCheckCode();
        withTypeInfoCode = javaParameters.getWithTypeInfoCode();
        withCodeComments = javaParameters.getWithCodeComments();

        generatorDescription = "/**\n"
                + " * Automatically generated by Zserio Java generator version " +
                JavaExtensionVersion.JAVA_EXTENSION_VERSION_STRING + " using Zserio core " +
                javaParameters.getZserioVersion() + ".\n"
                + " * Generator setup: " + javaParameters.getParametersDescription() + ".\n"
                + " */";
    }

    public PackedTypesCollector getPackedTypesCollector()
    {
        return packedTypesCollector;
    }

    public JavaNativeMapper getJavaNativeMapper()
    {
        return javaNativeMapper;
    }

    public String getJavaRootPackageName()
    {
        return javaRootPackageName;
    }

    public ExpressionFormatter getJavaExpressionFormatter()
    {
        return javaExpressionFormatter;
    }

    public ExpressionFormatter getJavaCaseExpressionFormatter()
    {
        return javaCaseExpressionFormatter;
    }

    public ExpressionFormatter getJavaSqlExpressionFormatter()
    {
        return javaSqlExpressionFormatter;
    }

    public ExpressionFormatter getJavaSqlLambdaExpressionFormatter()
    {
        return javaSqlLambdaExpressionFormatter;
    }

    public ExpressionFormatter getJavaLambdaExpressionFormatter()
    {
        return javaLambdaExpressionFormatter;
    }

    public boolean getWithWriterCode()
    {
        return withWriterCode;
    }

    public boolean getWithValidationCode()
    {
        return withValidationCode;
    }

    public boolean getWithRangeCheckCode()
    {
        return withRangeCheckCode;
    }

    public boolean getWithTypeInfoCode()
    {
        return withTypeInfoCode;
    }

    public boolean getWithCodeComments()
    {
        return withCodeComments;
    }

    public String getGeneratorDescription()
    {
        return generatorDescription;
    }

    private final PackedTypesCollector packedTypesCollector;

    private final JavaNativeMapper javaNativeMapper;
    private final String javaRootPackageName;

    private final ExpressionFormatter javaExpressionFormatter;
    private final ExpressionFormatter javaCaseExpressionFormatter;
    private final ExpressionFormatter javaSqlExpressionFormatter;
    private final ExpressionFormatter javaSqlLambdaExpressionFormatter;
    private final ExpressionFormatter javaLambdaExpressionFormatter;

    private final boolean withWriterCode;
    private final boolean withValidationCode;
    private final boolean withRangeCheckCode;
    private final boolean withTypeInfoCode;
    private final boolean withCodeComments;

    private final String generatorDescription;
}
